package com.lixw.jdbc.core.dao;

import com.lixw.jdbc.core.annotation.TableField;
import com.lixw.jdbc.core.annotation.TableId;
import com.lixw.jdbc.core.annotation.TableName;
import com.lixw.jdbc.core.enums.FillStrategy;
import com.lixw.jdbc.core.wrapper.FieldWrapper;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: AbstractTableMetaData
 * @Description:
 * @Author: xuweiLi
 * @Create: 2025/5/30 18:43
 **/
public class DefaultTableMetaDataImpl<T,P> implements TableMetaData<T,P>{

    private final Class<T> entityClass;
    // 主键类型
    private final Class<P> primaryKeyClass;

    public DefaultTableMetaDataImpl(Class<T> entityClass, Class<P> primaryKeyClass) {
        this.entityClass = entityClass;
        this.primaryKeyClass = primaryKeyClass;
    }

    public String getTableName() {
        if(entityClass.isAnnotationPresent(TableName.class)){
            TableName tableAnnotation = entityClass.getAnnotation(TableName.class);
            return tableAnnotation.value();
        }
        return entityClass.getSimpleName().toLowerCase();
    }

    public List<String> getTableFieldNames() {
        List<String> fieldNames = new ArrayList<>();

        Field[] declaredFields = entityClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            if(declaredField.isAnnotationPresent(TableField.class)){
                TableField filedAnnotation = declaredField.getAnnotation(TableField.class);
                if (filedAnnotation.exists()) {
                    String fieldName = filedAnnotation.value();
                    fieldNames.add(fieldName);
                }
            }else{
                fieldNames.add(declaredField.getName());
            }
        }
        return fieldNames;
    }

    @Override
    public List<FieldWrapper> getTableFieldWrappers(Object obj) {
        List<FieldWrapper> fieldWrappers = new ArrayList<>();

        Field[] declaredFields = entityClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            if(declaredField.isAnnotationPresent(TableId.class)){
                continue;
            }
            //如果目标对象不存在,则直接跳过 不修改
            boolean valueIsNull;
            try {
                valueIsNull = declaredField.get(obj) == null;
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
            FieldWrapper fieldWrapper = new FieldWrapper();
            if (declaredField.isAnnotationPresent(TableField.class)) {
                TableField filedAnnotation = declaredField.getAnnotation(TableField.class);
                //如果修改策略是 IGNORE忽略填充,但数据是空 跳过不修改
                if(filedAnnotation.updateStrategy() == FillStrategy.IGNORE && valueIsNull){
                    continue;
                }
                if (filedAnnotation.exists()) {
                    fieldWrapper.setFieldName(filedAnnotation.value());
                    fieldWrappers.add(fieldWrapper);
                }
            } else {
                if(valueIsNull){
                    continue;
                }
                fieldWrapper.setFieldName(declaredField.getName());
                fieldWrappers.add(fieldWrapper);
            }
        }
        return fieldWrappers;
    }

    public int getTableFieldCount() {
        int fieldCount = 0;
        Field[] declaredFields = entityClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            if(declaredField.isAnnotationPresent(TableField.class)){
                TableField filedAnnotation = declaredField.getAnnotation(TableField.class);
                if (filedAnnotation.exists()) {
                    fieldCount++;
                }
            }else{
                fieldCount++;
            }
        }
        return fieldCount;
    }

    @Override
    public Class<T> getEntityClass() {
        return entityClass;
    }

    @Override
    public Class<P> getPrimaryKeyClass() {
        return primaryKeyClass;
    }
}